package repository

import (
	"encoding/json"
	"gorm.io/gorm"
	"guliedu/model"
	"guliedu/utils"
	"mime/multipart"
	"time"
)

type IEduCourseRepository interface {
	// 增加课程
	Insert(c *model.EduCourse) error
	// 上传课程封面
	UploadCover(file multipart.File, fileSize int64) (string, int)
	// 查询课程
	Select(id string) (*model.EduCourse, error)
	// 更新课程
	Update(course *model.EduCourse) error
	// 查询所有课程
	SelectAllCourse() ([]model.EduCourse, error)
	// 删除课程
	Delete(id string) error
	// 查询首页热门课程
	SelectIndexHotCourse() ([]model.EduCourse, error)
	// 根据教师ID查询课程
	SelectCourseByTeacherID(id string) ([]model.EduCourse, error)
	// 查询前台课程
	SelectFrontCourse(page, pageSize, subjectParentID, subjectID int) ([]model.EduCourse, error)
	// 查询所有课程数
	SelectCourseCount() (int64, error)
	// 缓存首页热门课程
	CacheCourses([]model.EduCourse) error
	// 获取缓存
	GetCacheCourse() []model.EduCourse
}

func NewIEduCourseRepository() IEduCourseRepository {
	return &EduCourseRepository{mysqlDb: db}
}

type EduCourseRepository struct {
	mysqlDb *gorm.DB
}

func (e *EduCourseRepository) Insert(c *model.EduCourse) error {
	return e.mysqlDb.Create(&c).Error
}

func (e *EduCourseRepository) UploadCover(file multipart.File, fileSize int64) (string, int) {
	return utils.UploadFile(file, fileSize)
}

func (e *EduCourseRepository) Select(id string) (course *model.EduCourse, err error) {
	err = e.mysqlDb.Where("id = ?", id).Find(&course).Error
	return
}

func (e *EduCourseRepository) Update(course *model.EduCourse) error {
	return e.mysqlDb.Save(&course).Error
}

func (e *EduCourseRepository) SelectAllCourse() (courses []model.EduCourse, err error) {
	err = e.mysqlDb.Find(&courses).Error
	return
}

func (e *EduCourseRepository) Delete(id string) error {
	return e.mysqlDb.Where("id = ?", id).Delete(&model.EduCourse{}).Error
}

func (e *EduCourseRepository) SelectIndexHotCourse() (courses []model.EduCourse, err error) {
	err = e.mysqlDb.Order("view_count desc").Limit(8).Find(&courses).Error
	return
}

func (e *EduCourseRepository) SelectCourseByTeacherID(id string) (courses []model.EduCourse, err error) {
	err = e.mysqlDb.Where("teacher_id = ?", id).Find(&courses).Error
	return
}

func (e *EduCourseRepository) SelectFrontCourse(page, pageSize, subjectParentID, subjectID int) (courses []model.EduCourse, err error) {
	err = e.mysqlDb.Offset((page-1)*pageSize).Limit(pageSize).Scopes(WithSubjectParentID(subjectParentID), WithSubjectID(subjectID)).Find(&courses).Error
	return
}

func WithSubjectParentID(id int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if id != 0 {
			db.Where("subject_parent_id = ?", id)
		}
		return db
	}
}

func WithSubjectID(id int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if id != 0 {
			db.Where("subject_id = ?", id)
		}
		return db
	}
}

func (e *EduCourseRepository) SelectCourseCount() (count int64, err error) {
	err = e.mysqlDb.Model(&model.EduCourse{}).Count(&count).Error
	return
}

func (e *EduCourseRepository) CacheCourses(courses []model.EduCourse) error {
	coursesjson, _ := json.Marshal(courses)
	return client.Set("course:index", coursesjson, time.Hour*24).Err()
}

func (e *EduCourseRepository) GetCacheCourse() (courses []model.EduCourse) {
	coursesjson, _ := client.Get("course:index").Result()
	json.Unmarshal([]byte(coursesjson), &courses)
	return
}
